package tests.datastructures.queues;

import static org.junit.Assert.*;

import java.util.Iterator;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import datastructures.queues.CircularArrayQueue;
import datastructures.queues.QueueADT;

public class CicularArrayQueueTestCase {

	private QueueADT<String> fixture;

	@Before
	public void setUp() throws Exception {
		this.fixture = new CircularArrayQueue<String>(4);
	}

	@After
	public void tearDown() throws Exception {
		this.fixture = null;
	}

	@Test
	public void testInitialize() {
		assertTrue(this.fixture.isEmpty());
		assertEquals(0, this.fixture.size());
	}

	@Test
	public void testEnqueue() {
		String value1 = "Gatsby";
		this.fixture.enqueue(value1);
		assertEquals(1, this.fixture.size());
		assertEquals(value1, this.fixture.first());
	}

	@Test
	public void testDequeue() {
		String value1 = "Gatsby";
		this.fixture.enqueue(value1);
		assertEquals(1, this.fixture.size());
		assertEquals(value1, this.fixture.dequeue());
	}

	@Test
	public void testCircularStructure() {
		String value1 = "PHP";
		String value2 = "CakePHP";
		String value3 = "Python";
		String value4 = "django";
		String value5 = "script";
		String value6 = "language";
		this.fixture.enqueue(value1);
		this.fixture.enqueue(value2);
		this.fixture.enqueue(value3);
		this.fixture.enqueue(value4);
		assertEquals(value1, this.fixture.dequeue());
		assertEquals(value2, this.fixture.dequeue());
		assertEquals(value3, this.fixture.dequeue());
		assertEquals(value4, this.fixture.dequeue());

		this.fixture.enqueue(value5);
		this.fixture.enqueue(value6);
		assertEquals(value5, this.fixture.dequeue());
		assertEquals(value6, this.fixture.dequeue());
		assertEquals(0, this.fixture.size());
	}

	@Test
	public void testCircularStructureWithExpandingSize() {
		String value1 = "PHP";
		String value2 = "CakePHP";
		String value3 = "Python";
		String value4 = "django";
		String value5 = "script";
		String value6 = "language";
		this.fixture.enqueue(value1);
		this.fixture.enqueue(value2);
		this.fixture.enqueue(value3);
		this.fixture.enqueue(value4);
		this.fixture.enqueue(value5);
		this.fixture.enqueue(value6);
		assertEquals(6, this.fixture.size());

		assertEquals(value1, this.fixture.dequeue());
		assertEquals(value2, this.fixture.dequeue());
		assertEquals(value3, this.fixture.dequeue());
		assertEquals(value4, this.fixture.dequeue());
		assertEquals(value5, this.fixture.dequeue());
		assertEquals(value6, this.fixture.dequeue());
		assertEquals(0, this.fixture.size());
	}

	@Test
	public void testIterator() {
		String value1 = "PHP";
		String value2 = "CakePHP";
		String value3 = "Python";
		String value4 = "django";
		String value5 = "script";
		String value6 = "language";
		this.fixture.enqueue(value1);
		this.fixture.enqueue(value2);
		this.fixture.enqueue(value3);
		this.fixture.enqueue(value4);
		this.fixture.enqueue(value5);
		this.fixture.enqueue(value6);

		String[] tmpStringArray = new String[6];
		tmpStringArray[0] = value1;
		tmpStringArray[1] = value2;
		tmpStringArray[2] = value3;
		tmpStringArray[3] = value4;
		tmpStringArray[4] = value5;
		tmpStringArray[5] = value6;

		// foreach (shorthand)
		int index = 0;
		for (String s : this.fixture) {
			assertEquals(tmpStringArray[index++], s);
		}

		// longhand
		index = 0;
		Iterator<String> iterator = this.fixture.iterator();
		while (iterator.hasNext()) {
			String s = iterator.next();
			assertEquals(tmpStringArray[index++], s);
		}
	}
}

